import logging
import time
import traceback
from enum import Enum

import requests
import selenium
from lxml import etree
from selenium.webdriver.common.by import By
from seleniumwire import webdriver


def ASSIST_LOGGER(log_file_path="./output/spider.log"):
    """
    将日志输出到日志文件和控制台
    """
    if log_file_path in logging.Logger.manager.loggerDict:
        return logging.getLogger(log_file_path)
    logger = logging.getLogger(log_file_path)
    logger.setLevel(logging.INFO)
    formatter = logging.Formatter(
        '%(asctime)s - %(levelname)s - %(message)s')
    from ai.utils.utils_file import makedir_for_file
    makedir_for_file(log_file_path)

    # # 创建一个handler，用于将日志输出到控制台
    console = logging.StreamHandler()
    console.setLevel(logging.INFO)
    console.setFormatter(formatter)
    logger.addHandler(console)

    # 创建一个handler，用于写入日志文件
    file_handler = logging.FileHandler(
        filename=log_file_path, encoding='utf-8')
    file_handler.setFormatter(formatter)
    file_handler.setLevel(logging.INFO)
    logger.addHandler(file_handler)
    return logger


logger = ASSIST_LOGGER()


def handle_xpath(html_text: str, xpath):
    tree = etree.HTML(html_text)
    datas = tree.xpath(xpath)
    return datas


class REQUEST_METHOD(Enum):
    GET = 1
    POST = 2


def send_request(src, headers, method: REQUEST_METHOD = REQUEST_METHOD.GET):
    """
    发送请求, 如果顺利得到response并没有爆出任何错误,同时状态码为200, 则正常返回, 否则给出失败提示,
    需要调用者自行决定是否进行成功提示, 该函数不提供
    """
    response = None
    try:
        if method == REQUEST_METHOD.GET:
            response = requests.get(src, headers=headers)
        elif method == REQUEST_METHOD.POST:
            response = requests.post(src, headers=headers)
        if not hasattr(response, 'status_code'):
            raise RuntimeError()
        if not (response.status_code == 200 or response.status_code == 206):
            raise RuntimeError()
    except Exception as e:
        if hasattr(response, 'status_code'):
            logger.error(f"请求失败{e},code:{response.status_code}")
        else:
            logger.error(f"请求失败{e}")
        traceback.print_exc()
        return None
    return response


def do_a_click_to_a_driver(driver: webdriver.Chrome, button_location_xpath):
    """"""
    button = driver.find_element(By.XPATH, button_location_xpath)
    button.click()
    driver.implicitly_wait(1)
    time.sleep(1)
    # 获取网页源码
    html = driver.page_source
    return html, driver


def write_movie_ids_to_file(movie_id: list, file: str = './output/movie_ids.txt'):
    with open(file, 'w', encoding='utf-8') as f:
        for item in movie_id:
            f.write(item + '\n')


def read_movie_ids_from_file(file: str = './output/movie_ids.txt'):
    with open(file, 'r', encoding='utf-8') as f:
        res =  f.readlines()
        return [x.strip() for x in res]


def _join_path(path1, path2):
    if path1 is None or path2 is None or len(path1) == 0 or len(path2) == 0:
        return ""
    while path1[-1] == '/' or path1[-1] == '\\':
        path1 = path1[:-1]
    while path2[0] == '/' or path2[0] == '\\':
        path2 = path2[1:]
    return f'{path1}/{path2}'


def join_path(*args):
    lens = len(args)
    if lens == 0:
        return ""
    path = args[0]
    for i in range(1, lens):
        path = _join_path(path, args[i])
    return path
